package com.le.tester.onjava8.l_2_3;


/**
 * createTime：2023/2/1 13:49
 * description：检查能否克隆
 */

//无法克隆，未重写clone()
class Ordinary {
}

//重写克隆，未实现cloneable()接口
class WrongClone extends Ordinary {
    @Override
    public Object clone() throws CloneNotSupportedException {
        //调用object中的克隆方法
        return super.clone();
    }
}

//完美克隆,实现了克隆的接口
class IsCloneable extends Ordinary implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

//通过抛出异常，未关闭克隆
class NoMore extends IsCloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

class TryMore extends NoMore {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //调用父类的克隆方法,抛出异常
        return super.clone();
    }
}

class BackOn extends NoMore {
    private BackOn duplicate(BackOn b) {
        //只是单纯的new一个对象，并没有任何的操作;
        return new BackOn();
    }

    public Object clone() {
        //未调用超类的clone方法
        return duplicate(this);
    }

}

//final类无法被继承
final class ReallyNoMore extends NoMore {
}

public class CheckCloneable {

    public static Ordinary tryToClone(Ordinary ord) {
        String id = ord.getClass().getName();
        System.out.println("Attempting " + id);

        Ordinary x = null;
        if (ord instanceof Cloneable) {
            try {
                x = (Ordinary) ((IsCloneable) ord).clone();
                System.out.println("Cloned " + id);
            } catch (CloneNotSupportedException e) {
                System.out.println("Could not clone " + id);
            }
        } else {
            System.out.println("Does not implement Cloneable");
        }
        return x;
    }

    public static void main(String[] args) {
        //向上转型
        Ordinary[] ord = {
                new IsCloneable(), new WrongClone(), new NoMore(),
                new TryMore(), new BackOn(), new ReallyNoMore()
        };

        Ordinary x = new Ordinary();
        //并不能执行克隆方法,但是也并没有阻止你实现克隆方法
        //x.clone()
        for (Ordinary ord1 : ord) {
            tryToClone(ord1);
        }
    }
}
